package com.bpmn.flow.behavior;

import cn.hutool.core.util.EnumUtil;
import com.bpmn.common.constant.FlowableConstants;
import com.bpmn.common.enums.TaskOperationEnum;
import com.bpmn.utils.TaskConfigUtils;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.Activity;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;

/**
 * 自定义的【串行】的【多个】流程任务的 assignee 负责人的分配
 * <p>
 * 本质上，实现和 {@link BpmParallelMultiInstanceBehavior} 一样，只是继承的类不一样
 *
 * @author rain
 */
@Slf4j
@Setter
public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceBehavior {

    private BpmTaskCandidateInvoker taskCandidateInvoker;

    private TaskConfigUtils.TaskConfig taskConfig;

    public BpmSequentialMultiInstanceBehavior(Activity activity, AbstractBpmnActivityBehavior innerActivityBehavior) {
        super(activity, innerActivityBehavior);
        if (activity instanceof UserTask) {
            taskConfig = TaskConfigUtils.getTaskConfig((UserTask) activity);
        }
    }

    @Override
    protected int createInstances(DelegateExecution multiInstanceRootExecution) {
        log.info("[BpmSequentialMultiInstanceBehavior]初始化投票结果");
        int nrOfInstances = resolveNrOfInstances(multiInstanceRootExecution);
        //设置会签总数（用作条件判断）
        taskCandidateInvoker.initMultiInstance(multiInstanceRootExecution, nrOfInstances, taskConfig);
        return super.createInstances(multiInstanceRootExecution);
    }

    @Override
    public void leave(DelegateExecution execution) {
        log.info("[BpmSequentialMultiInstanceBehavior]开始设置投票结果");
        Object variable = execution.getVariableLocal(FlowableConstants.OPERATION_TYPE);
        if (variable != null) {
            TaskOperationEnum operationTypeEnum = EnumUtil.getBy(TaskOperationEnum::getCode, variable.toString());
            DelegateExecution miRootExecution = getMultiInstanceRootExecution(execution);
            taskCandidateInvoker.setMultiInstanceResult(miRootExecution, operationTypeEnum);
        }
        super.leave(execution);
    }

}
